﻿using Acme.SmartWMS.Common;
using Acme.SmartWMS.RBAC.Accounts.Dto;
using Polly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace Acme.SmartWMS.RBAC.Accounts
{
    public class AccountAppService : ApplicationService, IAccountAppService
    {
        /// <summary>
        /// 用户接口
        /// </summary>
        private readonly IRepository<Account, int> _accountrepository;

        /// <summary>
        /// 角色接口
        /// </summary>
        private readonly IRepository<Role, int> _rolerepository;

        /// <summary>
        /// 权限接口
        /// </summary>
        private readonly IRepository<Permission, int> _permissionrepository;

        /// <summary>
        /// 角色权限关联仓储接口
        /// </summary>
        private readonly IRepository<RolePermission, int> _rolePermissionrepository;

        /// <summary>
        /// 用户角色关联仓储接口
        /// </summary>
        private readonly IRepository<UserRole, int> _userRolerepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="accountrepository">用户接口</param>
        /// <param name="rolerepository">角色接口</param>
        /// <param name="permissionrepository">权限接口</param>
        /// <param name="rolePermissionrepository">角色权限关联仓储接口</param>
        /// <param name="userRolerepository">用户角色关联仓储接口</param>
        public AccountAppService(IRepository<Account, int> accountrepository, IRepository<Role, int> rolerepository, IRepository<Permission, int> permissionrepository, IRepository<RolePermission, int> rolePermissionrepository, IRepository<UserRole, int> userRolerepository)
        {
            _accountrepository = accountrepository;
            _rolerepository = rolerepository;
            _permissionrepository = permissionrepository;
            _rolePermissionrepository = rolePermissionrepository;
            _userRolerepository = userRolerepository;
        }




        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="accountName">账号</param>
        /// <param name="accountPass">密码</param>
        /// <returns>返回用户的信息</returns>
        public Task<Account> Log(string accountName, string accountPass)
        {
            var accountList = _accountrepository.FindAsync(m => m.AccountName == accountName && m.AccountPass == accountPass);
            return accountList;
        }

        /// <summary>
        /// 用户显示（分页）
        /// </summary>
        /// <param name="page">页面</param>
        /// <param name="limit">页容量</param>
        /// <param name="accountName">用户名</param>
        /// <returns></returns>
        public async Task<PagedResult> Display(int page, int limit, string? accountName)
        {
            var predicate = System.Linq.PredicateBuilder.New<Account>(true);
            predicate = predicate.And(m => m.IsNo == 1);
            if (!string.IsNullOrEmpty(accountName))
            {
                predicate = predicate.And(m => m.AccountName.Contains(accountName));
            }

            var accountList = await _accountrepository.GetListAsync(predicate);

            PagedResult pagedResult = new PagedResult();
            pagedResult.CurrentPage = accountList.Count();
            pagedResult.Queryable = accountList.Skip((page - 1) * limit).Take(limit).AsQueryable();
            return pagedResult;

        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> Delete(int id)
        {
            var accountDelete = _accountrepository.FindAsync(id).Result;
            accountDelete.IsNo = 0;
            await _accountrepository.UpdateAsync(accountDelete);
            return 1;
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>返回受影响行数</returns>
        public async Task<Account> Backfill(int id)
        {
            var accountList = await _accountrepository.FindAsync(id);
            return accountList;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="account">用户实体</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> Add(Account account)
        {
            var verify = await _accountrepository.CountAsync(m => m.AccountName == account.AccountName);
            if (verify > 0)
            {
                return -1;
            }

            var accountAdd = await _accountrepository.InsertAsync(account);
            return 1;
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="account">修改DTO</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> Update(UpdateAccountDto account)
        {
            var verify = await _accountrepository.CountAsync(m => m.AccountName == account.AccountName && m.Id != account.Id);
            if (verify > 0)
            {
                return -1;
            }

            var accountList = account.MapTo<Account>();
            await _accountrepository.UpdateAsync(accountList);
            return 1;
        }


        /// <summary>
        /// 获取用户数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<Role>> Select()
        {
            var predicate = System.Linq.PredicateBuilder.New<Role>(true);
            predicate = predicate.And(m => m.RoleState == 1);
            var roleList = await _rolerepository.GetListAsync(predicate);
            return roleList;

        }


        /// <summary>
        /// 五表联查
        /// </summary>
        /// <returns></returns>
        public async Task<List<Menu>> FiveTables(int id)
        {
            var accounts = await _accountrepository.GetListAsync();
            var userRoles = await _userRolerepository.GetListAsync();
            var roles = await _rolerepository.GetListAsync();
            var rolePermissions = await _rolePermissionrepository.GetListAsync();
            var permissions = await _permissionrepository.GetListAsync();

            var query = from a in accounts
                        join ur in userRoles on a.Id equals ur.UserId
                        join r in roles on ur.RoleId equals r.Id
                        join rp in rolePermissions on r.Id equals rp.RoleId
                        join p in permissions on rp.PermissionId equals p.Id
                        where a.Id == id
                        select new
                        {
                            p.Id,
                            p.IsDel,
                            p.PermissionName,
                            p.PageUrl,
                            p.Pid
                        };

            // 调试信息
            Console.WriteLine($"Query results count: {query.Count()}");

            var menuList = query.Select(m => new PermissionDto
            {
                Id = m.Id,
                Name = m.PermissionName,
                Url = m.PageUrl,
                State = m.IsDel == 1,
                PId = m.Pid
            }).ToList();

            var tmpList = query.Where(m => m.Pid == 0).ToList();


            var menus = GetChildrens(menuList, 0);
            //for (int i = 0; i < tmpList.Count; i++)
            //{
            //    var menu = new Menu();
            //    menu.Id = tmpList[i].Id;
            //    menu.Title = tmpList[i].PermissionName;
            //    menu.Url = tmpList[i].PageUrl;
            //    menu.State = tmpList[i].IsNo == 1 ? true : false;
            //    menu.Childrens = GetChildrens(menuList, menu.Id);
            //    menus.Add(menu);
            //}

            return menus;
        }

        /// <summary>
        /// 递归算法  : 指在当前方法内调用自己的这种现象。
        /// </summary>
        /// <param name="permissions"></param>
        /// <param name="pId"></param>
        /// <returns></returns>

        //public List<Menu> GetChildrens(List<PermissionDto> permissions, int pId)
        //{
        //    var menus = new List<Menu>();
        //    var tmpList = permissions.Where(m => m.PId == pId);
        //    if (!tmpList.Any())
        //        return menus;

        //    var list = tmpList.ToList();
        //    for (int i = 0; i < list.Count; i++)
        //    {
        //        var menu = new Menu();
        //        menu.Id = list[i].Id;
        //        menu.Title = list[i].Name;
        //        menu.Url = list[i].Url;
        //        menu.State = list[i].State;
        //        menu.Childrens = GetChildrens(permissions, menu.Id);
        //        menus.Add(menu);
        //    }

        //    return menus;
        //}



        public List<Menu> GetChildrens(List<PermissionDto> permissions, int pId, HashSet<int> visitedIds = null)
        {
            if (visitedIds == null)
            {
                visitedIds = new HashSet<int>();
            }

            var menus = new List<Menu>();
            var tmpList = permissions.Where(m => m.PId == pId);
            foreach (var item in tmpList)
            {
                var menu = new Menu
                {
                    Id = item.Id,
                    Title = item.Name,
                    Url = item.Url,
                    State = item.State
                };
                menu.Childrens = GetChildrens(permissions, item.Id, visitedIds);

                menus.Add(menu);
            }

            return menus;
        }




    }
}
